#ifndef INC_CONFIG_H
#define INC_CONFIG_H

#include <fstream>
#include <boost/config.hpp>
#include <boost/program_options.hpp>

namespace po = boost::program_options;

struct ConfigException : public std::exception { };

class Config
{
    const char* cfg_fname;

public:
    Config(const char* cfg_fname) : cfg_fname(cfg_fname)
    {
        if (this->cfg_fname == NULL) this->cfg_fname = "config.ini";
    }

    void read()
    {
        // Check for config file via command line param, else use default
        std::fstream config_fs(cfg_fname, std::fstream::in);
        if (!config_fs)
        {
            throw ConfigException();
        }

        po::options_description config_opts("Configuration");
        // TODO: Change these to ints
        config_opts.add_options()
        ("dynamo_deltat,c",     po::value<std::string>(&dynamo_delta_t)->default_value("-t0.1"), "Desc")
        ("dynamo_plugin,c",     po::value<std::string>(&dynamo_viewer)->default_value("-LGeomview"), "Desc")
        ("dynamo_others,c",     po::value<std::string>(&dynamo_others)->default_value("-E"), "Desc")
        ("dynamo_max_evts,c",   po::value<std::string>(&dynamo_max_evts)->default_value("-c10"), "Desc")
        ("dynamo_bin,c",            po::value<std::string>(&dynamo_bin)->default_value("dynarun"), "Path to dynarun binary.")
        ("dry_run,t",              po::bool_switch(&dry_run), "Dry run; only create the dynamo file.");

        boost::program_options::variables_map vm;
        po::store(po::parse_config_file(config_fs, config_opts), vm);
        po::notify(vm);
    }

    const char* getConfigFileName() const
    {
        return cfg_fname;
    }
    const std::string getDynamoBinPath() const
    {
        return dynamo_bin;
    }
    const std::string getDynamoOthers() const
    {
        return " " + dynamo_others;
    }
    const std::string getDynamoMaxEvts() const
    {
        return " " + dynamo_max_evts;
    }
    const std::string getDynamoDeltaT() const
    {
        return " " + dynamo_delta_t;
    }
    const std::string getDynamoViewer() const
    {
        return " " + dynamo_viewer;
    }
    bool isDryRun() const
    {
        return dry_run;
    }

private:
    std::string dynamo_bin;
    std::string dynamo_others;
    std::string dynamo_max_evts;
    std::string dynamo_delta_t;
    std::string dynamo_viewer;
    bool dry_run;
};

#endif /* INC_CONFIG_H */
